class MassDriverFire extends InstantFire;

var() class<ShockBeamEffect> BeamEffectClass;
var() float HeadShotRadius;
var() float HeadShotDamageMult;
var() class<DamageType> DamageTypeHeadShot;

#exec OBJ LOAD FILE=..\Sounds\WeaponSounds.uax

function DoFireEffect()
{
    local Vector StartTrace;
    local Rotator R, Aim;

    Instigator.MakeNoise(1.0);

    StartTrace = Instigator.Location + Instigator.EyePosition();

    Aim = AdjustAim(StartTrace, AimError);
	R = rotator(vector(Aim) + VRand()*FRand()*Spread);
    DoTrace(StartTrace, R);
}

function InitEffects()
{
    Super.InitEffects();
    if ( FlashEmitter != None )
		Weapon.AttachToBone(FlashEmitter, 'tip');
}



function DoTrace(Vector Start, Rotator Dir)
{
	local Vector X, End, HitLocation, HitNormal;
	local Actor Other;
	local int Damage;
	local float dist;

	X = Vector(Dir);
	End = Start + TraceRange * X;

	foreach Weapon.TraceActors(class'Actor', Other, HitLocation, HitNormal, End, Start)
	{
		if(Other == Instigator)
			continue;

		if(BigShieldSphere(Other)!=none && self.Owner!=none && pawn(self.Owner)!=none && BigShieldSphere(Other).Shield.myteam==pawn(self.Owner).PlayerReplicationInfo.Team.TeamIndex)
	       continue;

		if(Other.bWorldGeometry)
		{
			if(WeaponAttachment(Weapon.ThirdPersonActor) != None)
				WeaponAttachment(Weapon.ThirdPersonActor).UpdateHit(Other, HitLocation, HitNormal);

			break;
		}

		Damage = DamageMin;

		if((DamageMin != DamageMax) && (FRand() > 0.5))
			Damage += Rand(1 + DamageMax - DamageMin);

		if(Other.IsA('Pawn'))
		{
				Damage = DamageMin;
				if ( (DamageMin != DamageMax) && (FRand() > 0.5) )
				Damage += Rand(1 + DamageMax - DamageMin);
                                Damage = Damage * DamageAtten;

            if ( (Pawn(Other) != None) && Other.GetClosestBone( HitLocation, X, dist, 'head', HeadShotRadius ) == 'head' )
               Other.TakeDamage(Damage*HeadShotDamageMult, Instigator, HitLocation, Momentum*X, DamageTypeHeadShot);
            else
            {
               Other.TakeDamage(Damage, Instigator, HitLocation, Momentum*X, DamageType);
            }

		}

		Damage = Damage * DamageAtten;
		if (Pawn(Other) == None)
			Other.TakeDamage(Damage, Instigator, HitLocation, Momentum * X, DamageType);
		HitNormal = Vect(0,0,0);
	}

	if(Other == None)
	{
		HitLocation = End;
		HitNormal = Vect(0,0,0);
	}

	SpawnBeamEffect(Start, Dir, HitLocation, HitNormal, 0);
}



function SpawnBeamEffect(Vector Start, Rotator Dir, Vector HitLocation, Vector HitNormal, int ReflectNum)
{
    local ShockBeamEffect Beam;

    Beam = Spawn(BeamEffectClass,,, Start, Dir);
    if (ReflectNum != 0) Beam.Instigator = None; // prevents client side repositioning of beam start
    Beam.AimAt(HitLocation, HitNormal);
}


function StartBerserk()
{
    FireRate = default.FireRate * 0.5;
    FireAnimRate = default.FireAnimRate * 0.5;
}

function StopBerserk()
{
    FireRate = default.FireRate;
    FireAnimRate = default.FireAnimRate;
}

defaultproperties
{
     BeamEffectClass=Class'Taskforces.MassDriverBeamEffect'
     HeadShotRadius=8.000000
     HeadShotDamageMult=3.000000
     DamageTypeHeadShot=Class'Taskforces.MassDriverHeadShotDamType'
     DamageType=Class'Taskforces.MassDriverDamType'
     DamageMin=100
     DamageMax=120
     TraceRange=32768.000000
     Momentum=120000.000000
     bWaitForRelease=True
     bModeExclusive=False
     FireAnimRate=5.000000
     FireSound=Sound'TFMedia.MassDriverFire'
     FireForce="ShockRifleFire"
     FireRate=4.000000
     AmmoClass=Class'Taskforces.MassDriverAmmo'
     AmmoPerFire=1
     ShakeRotTime=2.000000
     ShakeOffsetMag=(X=-26.000000,Y=5.000000,Z=5.000000)
     ShakeOffsetRate=(X=-800.000000)
     ShakeOffsetTime=5.000000
     BotRefireRate=0.500000
     aimerror=400.000000
}
